﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Uber.Messages;
using System.Data;
using Uber.Storage;
using Uber.HabboHotel.GameClients;

namespace Uber.HabboHotel.Quests
{
    class QuestManager
    {
        public List<Quest> Quests;

        public QuestManager()
        {
            this.Quests = new List<Quest>();
        }

        public void InitQuests()
        {
            this.Quests = null;
            this.Quests = new List<Quest>();

            DataTable Data = null;

            using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient())
            {
                Data = dbClient.ReadDataTable("SELECT id,type,action,needofcount,level_num,pixel_reward FROM quests WHERE enabled = '1' ORDER by level_num");
            }

            if (Data == null)
            {
                return;
            }

            foreach (DataRow Row in Data.Rows)
            {

                this.Quests.Add(new Quest((uint)Row["id"], (string)Row["type"], (string)Row["action"], (int)Row["needofcount"], (int)Row["level_num"], (int)Row["pixel_reward"]));
            }

            UberEnvironment.GetLogging().WriteLine("Initialized " + this.Quests.Count + " Quests.");
        }

        public void UpdateQuest(uint Id, GameClient Session)
        {
            Session.GetHabbo().CurrentQuestProgress++;

            using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient())
            {
                dbClient.ExecuteQuery("UPDATE users SET quest_progress = quest_progress + 1 WHERE id = '" + Session.GetHabbo().Id + "' LIMIT 1");
            }

            UberEnvironment.GetGame().GetQuestManager().HandleQuest(Id, Session);
        }

        public int GetHighestLevelForType(string Type)
        {
            int i = 0;

            foreach (Quest Q in this.Quests)
            {
                if (Q.Type == Type)
                {
                    i++;
                }
            }

            return i;
        }

        public uint GetQuestIdBy1More(int LevelType, string Type)
        {
            foreach (Quest Q in this.Quests)
            {
                if (Q.Type == Type)
                {
                    if (Q.Level == LevelType + 1)
                    {
                        return Q.QuestId();
                    }
                }
            }

            return 0;
        }

        public void ActivateNextQuest(GameClient Session)
        {
            Quest Quest = GetQuest(Session.GetHabbo().LastQuestId); if (Quest == null) { return; }

            string Type = Quest.Type.ToLower();
            int Level = 0;

            switch (Type)
            {
                case "social":
                    Level = Session.GetHabbo().LevelSocial;
                    break;
                case "room_builder":
                    Level = Session.GetHabbo().LevelBuilder;
                    break;
                case "identity":
                    Level = Session.GetHabbo().LevelIdentity;
                    break;
                case "explore":
                    Level = Session.GetHabbo().LevelExplorer;
                    break;
            }

            if (GetQuestIdBy1More(Level, Type) != 0)
            {
                this.HandleQuest(GetQuestIdBy1More(Level, Type), Session);
            }
        }

        public ServerMessage SerializeQuestList(GameClient Session)
        {
            ServerMessage Message = new ServerMessage(800);
            Message.AppendInt32(4); // explore, social, identity, room_builder() 4

            this.ParseNeed(Session, Message);

            Message.AppendInt32(1); // end line

            return Message;
        }

        public Quest GetQuest(uint Id)
        {
            foreach (Quest Quest in this.Quests)
            {
                if (Quest.QuestId() == Id)
                {
                    return Quest;
                }
            }

            return null;
        }

        public void HandleQuest(uint Id, GameClient Session)
        {
            if (Session == null)
            {
                return;
            }

            if (Session.GetHabbo().CurrentQuestId != Id)
            {
                Session.GetHabbo().CurrentQuestId = Id;
                Session.GetHabbo().CurrentQuestProgress = 0;

                using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient())
                {
                    dbClient.AddParamWithValue("uid", Session.GetHabbo().Id);
                    dbClient.AddParamWithValue("qid", Id);

                    dbClient.ExecuteQuery("UPDATE users SET quest_id = @qid, quest_progress = '0' WHERE id = @uid LIMIT 1");
                }
            }

            if (Id == 0)
            {
                Session.SendMessage(SerializeQuestList(Session));

                ServerMessage Message = new ServerMessage(803);
                Session.SendMessage(Message);
            }
            else
            {
                Quest Quest = this.GetQuest(Id);

                if (Quest == null)
                {
                    return;
                }

                if (Quest.NeedForLevel <= Session.GetHabbo().CurrentQuestProgress)
                {
                    CompleteQuest(Id, Session);
                    return;
                }
                else
                {
                    ServerMessage Message = new ServerMessage(802);

                    Quest.Serialize(Message, Session, true);

                    Session.SendMessage(Message);
                }
            }
        }

        public void CompleteQuest(uint Id, GameClient Session)
        {
            Session.GetHabbo().CurrentQuestId = 0;
            Session.GetHabbo().LastQuestId = Id;

            using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient())
            {
                dbClient.AddParamWithValue("userid", Session.GetHabbo().Id);
                dbClient.AddParamWithValue("questid", Id);
                dbClient.ExecuteQuery("UPDATE users SET quest_id = '0',quest_progress = '0', lev_" + GetQuest(Id).Type.Replace("room_", "") + " = lev_" + GetQuest(Id).Type.Replace("room_", "") + " + 1 WHERE id = @userid LIMIT 1");
                dbClient.ExecuteQuery("INSERT INTO user_quests (user_id,quest_id) VALUES (@userid,@questid)");
            }

            switch (GetQuest(Id).Type.ToLower())
            {
                case "identity":
                    Session.GetHabbo().LevelIdentity++;
                    break;
                case "room_builder":
                    Session.GetHabbo().LevelBuilder++;
                    break;
                case "social":
                    Session.GetHabbo().LevelSocial++;
                    break;
                case "explore":
                    Session.GetHabbo().LevelExplorer++;
                    break;
            }

            Session.GetHabbo().LoadQuests();

            int Amount = 50;
            Session.GetHabbo().ActivityPoints += Amount;
            Session.GetHabbo().UpdateActivityPointsBalance(true, Amount);

            ServerMessage Message = new ServerMessage(801);

            Quest Quest = GetQuest(Id);

            if (Quest == null)
            {
                return;
            }

            Quest.Serialize(Message, Session, true);
            this.ParseNeed(Session, Message);
            Message.AppendInt32(1);
            Session.SendMessage(Message);

            Session.GetHabbo().CurrentQuestProgress = 0;
        }

        public void ParseNeed(GameClient Session, ServerMessage Message)
        {
            Boolean DidSocial = false;
            Boolean DidBuilder = false;
            Boolean DidId = false;
            Boolean DidExplorer = false;

            foreach (Quest Quest in this.Quests)
            {
                if (Quest.QuestId() == Session.GetHabbo().CurrentQuestId)
                {
                    Quest.Serialize(Message, Session, false);

                    switch (Quest.Type.ToLower())
                    {
                        case "social":
                            DidSocial = true;
                            break;
                        case "room_builder":
                            DidBuilder = true;
                            break;
                        case "identity":
                            DidId = true;
                            break;
                        case "explore":
                            DidExplorer = true;
                            break;
                    }
                }

                if (Quest.Type.ToLower() == "room_builder" && !DidBuilder && Quest.Level == GetHighestLevelForType("room_builder") && Session.GetHabbo().LevelBuilder == GetHighestLevelForType("room_builder"))
                {
                    Quest.Serialize(Message, Session, false);
                    DidBuilder = true;
                }

                if (Quest.Type.ToLower() == "social" && !DidSocial && Quest.Level == GetHighestLevelForType("social") && Session.GetHabbo().LevelSocial == GetHighestLevelForType("social"))
                {
                    Quest.Serialize(Message, Session, false);
                    DidSocial = true;
                }

                if (Quest.Type.ToLower() == "identity" && !DidId && Quest.Level == GetHighestLevelForType("identity") && Session.GetHabbo().LevelIdentity == GetHighestLevelForType("identity"))
                {
                    Quest.Serialize(Message, Session, false);
                    DidId = true;
                }

                if (Quest.Type.ToLower() == "explore" && !DidExplorer && Quest.Level == GetHighestLevelForType("explore") && Session.GetHabbo().LevelExplorer == GetHighestLevelForType("explore"))
                {
                    Quest.Serialize(Message, Session, false);
                    DidExplorer = true;
                }

                if (Quest.Type.ToLower() == "room_builder" && !DidBuilder && Quest.Level == Session.GetHabbo().LevelBuilder + 1)
                {
                    Quest.Serialize(Message, Session, false);
                    DidBuilder = true;
                }

                if (Quest.Type.ToLower() == "social" && !DidSocial && Quest.Level == Session.GetHabbo().LevelSocial + 1)
                {
                    Quest.Serialize(Message, Session, false);
                    DidSocial = true;
                }

                if (Quest.Type.ToLower() == "identity" && !DidId && Quest.Level == Session.GetHabbo().LevelIdentity + 1)
                {
                    Quest.Serialize(Message, Session, false);
                    DidId = true;
                }

                if (Quest.Type.ToLower() == "explore" && !DidExplorer && Quest.Level == Session.GetHabbo().LevelExplorer + 1)
                {
                    Quest.Serialize(Message, Session, false);
                    DidExplorer = true;
                }
            }
        }
    }
}
